/**
 * API 调用模块
 * 处理与后端 API 的所有通信
 */

class OCRApi {
    constructor(baseUrl = '') {
        // 如果没有提供 baseUrl，使用相对路径（同一服务器）
        // 如果提供了 baseUrl，使用完整 URL（跨域访问）
        this.baseUrl = baseUrl || '';
        this.apiPrefix = '/api';
        this.timeout = 30000; // 30 秒超时
    }

    /**
     * 设置 API 基础 URL
     * @param {string} url - 完整的 API 地址，如 'http://192.168.10.11:8000' 或空字符串表示相对路径
     */
    setBaseUrl(url) {
        this.baseUrl = url || '';
    }

    /**
     * 获取完整的 API 端点 URL
     */
    getApiUrl(endpoint) {
        if (this.baseUrl) {
            // 如果设置了 baseUrl，使用完整 URL
            return `${this.baseUrl}${this.apiPrefix}${endpoint}`;
        } else {
            // 否则使用相对路径
            return `${this.apiPrefix}${endpoint}`;
        }
    }

    /**
     * 健康检查
     */
    async healthCheck() {
        try {
            const response = await axios.get(this.getApiUrl('/health'), {
                timeout: this.timeout
            });
            return response.data;
        } catch (error) {
            throw new Error(`健康检查失败: ${error.message}`);
        }
    }

    /**
     * 处理视频文件 - 纯文本识别
     * @param {File} file - 视频文件
     * @param {Object} options - 选项
     * @param {number} options.sampleRate - 采样率
     * @param {number} options.minScore - 最小置信度
     * @param {Function} options.onProgress - 进度回调
     */
    async processVideoFile(file, options = {}) {
        const formData = new FormData();
        formData.append('file', file);

        if (options.sampleRate) {
            formData.append('sample_rate', options.sampleRate);
        }
        if (options.minScore) {
            formData.append('min_score', options.minScore);
        }

        try {
            const response = await axios.post(
                this.getApiUrl('/process-video-text-only'),
                formData,
                {
                    // 不要手动设置 Content-Type，让 axios 自动处理
                    // axios 会自动添加正确的 boundary
                    timeout: this.timeout * 2, // 视频处理需要更长时间
                    onUploadProgress: (progressEvent) => {
                        if (options.onProgress) {
                            const percentCompleted = Math.round(
                                (progressEvent.loaded * 100) / progressEvent.total
                            );
                            options.onProgress(percentCompleted);
                        }
                    }
                }
            );
            return response.data;
        } catch (error) {
            throw new Error(`视频处理失败: ${error.message}`);
        }
    }

    /**
     * 处理视频流 - SSE 流式处理
     * @param {File} file - 视频文件
     * @param {Object} options - 选项
     * @param {number} options.sampleRate - 采样率
     * @param {number} options.minScore - 最小置信度
     * @param {Function} options.onData - 数据回调
     * @param {Function} options.onProgress - 进度回调
     * @param {Function} options.onError - 错误回调
     * @param {Function} options.onComplete - 完成回调
     */
    async processVideoStream(file, options = {}) {
        const formData = new FormData();
        formData.append('file', file);
        
        if (options.sampleRate) {
            formData.append('sample_rate', options.sampleRate);
        }
        if (options.minScore) {
            formData.append('min_score', options.minScore);
        }

        try {
            const response = await fetch(this.getApiUrl('/process-video-stream'), {
                method: 'POST',
                body: formData
            });

            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                buffer += decoder.decode(value, { stream: true });
                const lines = buffer.split('\n');
                buffer = lines.pop(); // 保留未完成的行

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        try {
                            const data = JSON.parse(line.slice(6));
                            
                            if (data.type === 'metadata') {
                                if (options.onProgress) {
                                    options.onProgress({
                                        type: 'metadata',
                                        totalFrames: data.total_frames,
                                        fps: data.fps
                                    });
                                }
                            } else if (data.type === 'frame') {
                                if (options.onData) {
                                    options.onData({
                                        type: 'frame',
                                        frameIndex: data.frame_index,
                                        texts: data.texts,
                                        timestamp: data.timestamp
                                    });
                                }
                            } else if (data.type === 'complete') {
                                if (options.onComplete) {
                                    options.onComplete({
                                        type: 'complete',
                                        totalTexts: data.total_texts,
                                        processingTime: data.processing_time
                                    });
                                }
                            } else if (data.type === 'error') {
                                if (options.onError) {
                                    options.onError({
                                        type: 'error',
                                        message: data.message
                                    });
                                }
                            }
                        } catch (e) {
                            console.error('解析 SSE 数据失败:', e);
                        }
                    }
                }
            }
        } catch (error) {
            throw new Error(`流式处理失败: ${error.message}`);
        }
    }

    /**
     * 处理图像 - 用于摄像头拍照
     * @param {Blob} imageBlob - 图像 Blob
     * @param {Object} options - 选项
     */
    async processImage(imageBlob, options = {}) {
        const formData = new FormData();
        formData.append('file', imageBlob, 'capture.jpg');

        if (options.minScore) {
            formData.append('min_score', options.minScore);
        }

        try {
            const response = await axios.post(
                this.getApiUrl('/process-video-text-only'),
                formData,
                {
                    // 不要手动设置 Content-Type，让 axios 自动处理
                    timeout: this.timeout
                }
            );
            return response.data;
        } catch (error) {
            throw new Error(`图像处理失败: ${error.message}`);
        }
    }

    /**
     * 处理图像流 - SSE 流式处理（用于摄像头拍照）
     * @param {Blob} imageBlob - 图像 Blob
     * @param {Object} options - 选项
     * @param {number} options.minScore - 最小置信度
     * @param {Function} options.onData - 数据回调
     * @param {Function} options.onError - 错误回调
     * @param {Function} options.onComplete - 完成回调
     */
    async processImageStream(imageBlob, options = {}) {
        const formData = new FormData();
        formData.append('file', imageBlob, 'capture.jpg');

        if (options.minScore) {
            formData.append('min_score', options.minScore);
        }

        try {
            const response = await fetch(
                this.getApiUrl('/process-image-stream'),
                {
                    method: 'POST',
                    body: formData
                }
            );

            if (!response.ok) {
                throw new Error(`HTTP error! status: ${response.status}`);
            }

            const reader = response.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                buffer += decoder.decode(value, { stream: true });
                const lines = buffer.split('\n');

                // 保留最后一行（可能不完整）
                buffer = lines.pop() || '';

                for (const line of lines) {
                    if (line.startsWith('data: ')) {
                        try {
                            const data = JSON.parse(line.slice(6));

                            if (data.type === 'metadata') {
                                if (options.onProgress) {
                                    options.onProgress({
                                        type: 'metadata',
                                        filename: data.filename,
                                        imageShape: data.image_shape
                                    });
                                }
                            } else if (data.type === 'frame') {
                                if (options.onData) {
                                    options.onData({
                                        type: 'frame',
                                        texts: data.texts,
                                        textCount: data.text_count
                                    });
                                }
                            } else if (data.type === 'complete') {
                                if (options.onComplete) {
                                    options.onComplete({
                                        type: 'complete',
                                        totalTexts: data.total_texts,
                                        processingTime: data.processing_time
                                    });
                                }
                            } else if (data.type === 'error') {
                                if (options.onError) {
                                    options.onError({
                                        type: 'error',
                                        message: data.message
                                    });
                                }
                            }
                        } catch (e) {
                            console.error('解析 SSE 数据失败:', e);
                        }
                    }
                }
            }
        } catch (error) {
            throw new Error(`图像流处理失败: ${error.message}`);
        }
    }

    /**
     * 获取 API 信息
     */
    async getInfo() {
        try {
            const response = await axios.get(`${this.baseUrl}/`, {
                timeout: this.timeout
            });
            return response.data;
        } catch (error) {
            throw new Error(`获取 API 信息失败: ${error.message}`);
        }
    }
}

// 创建全局 API 实例
const ocrApi = new OCRApi();

